<%@ Page Language="C#" AutoEventWireup="true" Inherits="Documentation_CRUD_Edit" Codebehind="Edit.aspx.cs" %>

<%@ Register Assembly="Pampa.CRUD" Namespace="Pampa.CRUD.UI.CustomControls" TagPrefix="cc1" %>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
    <link href="../../Css/Layout.css" rel="stylesheet" type="text/css"/>           
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <span class="title">Entity Edit</span>
        <br />
        <br />
        The main idea of this control is to manage the edition of an entity.
        An entity is understood as a class of the Model which implement Pampa.CRUD.Core.IActiveRecord (see <a href="Entities.aspx">Entities</a>).
        You can control how the data of the entity is edited through an XML configuration.
        Most of common problems related to build an edit page are resolved by the framework. <br />
        <br />
        <br />
        <br />


        <span class="subtitle">Simple Entity Editing</span>
        <br />
        <br />
        In order to understand working of Entity Edit we present a very simple class to edit with just 2 properties.
        <br />
        <br />
                
<pre class="codeBlock" style="width:auto">
<span class="keyword">public class</span> SimpleEntity : Pampa.CRUD.Core.IActiveRecord
{
   <span class="keyword">private string</span> property1;
   <span class="keyword">private int</span> property2;

   <span class="keyword">public</span> SimpleEntity()
   {
   } 

   <span class="keyword">public int</span> Property1
   {
      <span class="keyword">get</span> { <span class="keyword">return</span> property1; }
      <span class="keyword">set</span> { property1 = value; }
   }

   <span class="keyword">public int</span> Property2
   {
      <span class="keyword">get</span> { <span class="keyword">return</span> property2; }
      <span class="keyword">set</span> { property2 = value; }
   }

   <span class="keyword">public bool</span> IsNew
   {
      <span class="keyword">get</span> { <span class="keyword">return</span> true; }
   }

   <span class="keyword">public void</span> Save()
   {
      <span class="comment">	// TODO</span>
   }
 
   ...
 
} 
</pre>
			
        <br />
        <br />
                   
        
        
        <span class="subtitle">XML Configuration</span>
        <br />
        <br />
        Firstly, we need to say Pampa.Net were are the configuration files. 
        To do this we just need to add few lines into our web.config file.<br />
        Suppose we have a folder called Entities in the root of our site, then web.config will be like this:

<pre class="codeBlock">
&lt;configSections&gt;
   &lt;section name="pampa" type="System.Configuration.NameValueFileSectionHandler"/&gt;
   ...
&lt;/configSections&gt;

&lt;pampa&gt;
   &lt;add key="crud.entities.path" value="Entities"/&gt;
&lt;/pampa&gt;        
</pre>	

Now, this will be our configuration file for the edition of a SimpleEntity:
        
<pre class="codeBlock">
&lt;entity xmlns="urn:pampa-config"&gt;
  ...
  &lt;edit&gt;
    &lt;HeaderGroup Id="MainData" Title="Main Data" Columns="2"&gt;
      &lt;Items&gt;
        &lt;TextItem Id="Property1" Label="Property1" LabelWidth="150" ValueWidth="200" MaxLength="20"&gt;
        &lt;/TextItem&gt;
        &lt;StaticComboItem Id="Property2" Label="Property2" LabelWidth="150" ValueWidth="200"&gt;
          &lt;ComboItems&gt;
            &lt;Item Text="Item 1" Value="1"/&gt;
            &lt;Item Text="Item 2" Value="2"/&gt;
            &lt;Item Text="Item 3" Value="3"/&gt;
          &lt;/ComboItems&gt;
        &lt;/StaticComboItem>
      &lt;/Items&gt;
    &lt;/HeaderGroup&gt;
  &lt;/edit&gt;
  ...  
&lt;/entity&gt;
</pre>

        <br />
        We can see above the definition of one group of data with two items. First one is a textbox and the second one is a drop down list 
        with a static list of items. For a full description of all the possibilities you can configure for an Entity Edit component please see <a href="../Others/Configuration.aspx">XML Configuration</a>
        <br />
        <br />
        <br />
        
        
        
        <span class="subtitle">Code Behind</span>
        <br />
        <br />
        In order to edit a new instance of our SimpleEntity class we create the instance, set some values for its attributes and then
        we pass the instance to the EntityEdit control. 
        <br />
        
<pre class="codeBlock">
<span class="keyword">protected void</span> Page_Load(<span class="keyword">object</span> sender, <span class="className">EventArgs</span> e)
{
   <span class="className">SimpleEntity</span> simpleEntity = <span class="keyword">new</span> <span class="className">SimpleEntity</span>();
   simpleEntity.Property1 = <span class="string">"Property 1"</span>;
   simpleEntity.Property2 = <span class="string">2</span>;
   <span class="keyword">this</span>.EntityEdit1.Entity = simpleEntity;
}
</pre>

		Now, if we do not do anything else, before the page is render, the framework will check the type of the entity associated to the 
		EntityEdit and then it will look for a config file called SimpleEntity.crud.xml (class name plus ".crud.xml") 
		in the folder we indicate in the web.config (In our case this folder is 'Entities').
		<br /><br />
        However, if we wanted to pin down which is the configuration file that the framework has to load we could use LoadConfiguration method.
<pre>
EntityEdit1.LoadConfiguration("MyEntityConfiguration");
</pre>
        and the framework will look for a file called MyEntityConfiguration.crud.xml in Entities folder.
        It is particularly useful when we have different configuration files for the same Entity and we want to load each of these files depending on the context.
        <br />
        <br />              
        <br />   
                         
                        
                        
        <span class="subtitle">Entity Edit Working</span>       
        <br />         
        <br />
        Here we can see an EntityEdit control showing the instance of SimpleEntity class built above.
        <br />
        <br />
        <cc1:EntityEdit ID="EntityEdit1" runat="server" Width="500px"/>
        <br />         
        <br />



        <span class="subtitle">Save Button</span>       
        <br />         
        <br />
        In order to save the data the easiest way is using a Save Button. 
        It has a property called "EntityEditID" that indicate the button which entity has to be saved.
        When the button is clicked data is validated (see below Client Validations) 
        and if everything is ok Save method from the corresponding entity is called.
        Also, it is possible to define an action to do after a successful save.
        <br />
        <br />
        Here we can see a save button for the EntityEdit component shown above. 
        We will set these properties:<br/>
        
<pre>
Text = "Save"
EntityEditID = "EntityEdit1"
OnSuccess = "alert('ok')"
</pre>
		
        <cc1:entityeditsavebutton id="btnAccept" runat="server" width="64px"
            text="Save" EntityEditID="EntityEdit1" OnSuccess="alert('ok')" />

        <br />         
        <br />
        <br />
        
        
        
        <span class="subtitle">Property Types</span>       
        <br />         
        <br />
        Types of properties that will be editing for an EntityEdit can be any native type or any class that implement IEntity.
        The framework will take the value gotten from the page and will trate to convert this value to the correct type. 
        In the case of entity controls, this value will be the id of the selected item (see <a href="EntityControls.aspx">Entity Controls</a>).
        <br/>
        What happen if the property type is an Entity?<br/>
        For example, the property "Nationality" of a "Person" could be of type "Country".
        In that case class Country must have defined a particular static method: 
        <br />
        
<pre>
<span class="keyword">object</span> ParseID(<span class="keyword">string</span> strID) 
</pre>

        which will be used by the framework to get an id object from the string value coming from the page and then to can get the correct Country.<br />
        The procedure is something like this:
        <br />

<pre>
<span class="keyword">object</span> countryID = <span class="className">Country</span>.ParseID(strID); <span class="comment">// strID = string value coming from the page</span>
<span class="className">Country</span> country = <span class="className">Country</span>.Find(countryID);
person.Nationality = country;
</pre>        

        <br />         
        
        
        
        <span class="subtitle">Client Validations</span>       
        <br />         
        <br />
        It is possible to add client side validations just modifying our XML Configuration.
        There is three different types of validations:<br/>
        Required Validation: This type just allow to set a field like mandatory.<br />
        Pattern Validation: This type allow to define a regular expression that should be follow by the data. 
        It is very useful, for example, for e-mail validations.<br />
        Range Validation: This type allow to validate data types and ranges. 
        For example, we could validate that certain field has to be filled with an integer gather than 0.
        <br />         
        <br />
        Again, please see <a href="../Others/Configuration.aspx">XML Configuration</a> for a full description of validations configuration.
        <br />         
        <br />
		Below we can see an example of an EntityEdit with validations. 
		<br />
		<br />

<pre class="codeBlock">
<span class="keyword">public class</span> <span class="className">Person</span> : Pampa.CRUD.Core.<span class="className">IEntity</span>
{
    <span class="keyword">string</span> name;
    <span class="keyword">string</span> email;
    <span class="keyword">int</span>? age;

    <span class="keyword">public string</span> Name
    {
        <span class="keyword">get</span> { <span class="keyword">return</span> name; }
        <span class="keyword">set</span> { name = value; }
    }

    <span class="keyword">public string</span> Email
    {
        <span class="keyword">get</span> { <span class="keyword">return</span> email; }
        <span class="keyword">set</span> { email = value; }
    }

    <span class="keyword">public int</span>? Age
    {
        <span class="keyword">get</span> { <span class="keyword">return</span> age; }
        <span class="keyword">set</span> { age = value; }
    }

    ...
}
</pre> 

<pre class="codeBlock">
...
&lt;HeaderGroup Id="MainDataPerson" Title="Person Main Data" Columns="1"&gt;
  &lt;Items&gt;
    &lt;TextItem Id="Name" Label="Name" LabelWidth="150" ValueWidth="200" MaxLength="20"&gt;
      &lt;Validations&gt;
        &lt;RequiredValidation ErrorMessage="Name is required"/&gt;
      &lt;/Validations&gt;
    &lt;/TextItem&gt;
    &lt;TextItem Id="Email" Label="E-mail" LabelWidth="150" ValueWidth="200" MaxLength="20"&gt;
      &lt;Validations&gt;
        &lt;RequiredValidation ErrorMessage="Email is required"/&gt;
        &lt;PatternValidation Expression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" ErrorMessage="E-mail is wrong."/&gt;
      &lt;/Validations&gt;
    &lt;/TextItem&gt;
    &lt;TextItem Id="Age" Label="Age" LabelWidth="150" ValueWidth="50" MaxLength="3"&gt;
      &lt;Validations&gt;
        &lt;RangeValidation DataType="Integer" ErrorMessage="Age must be numeric, positive and less than 100." MinValue="0" MaxValue="100"/&gt;
      &lt;/Validations&gt;
    &lt;/TextItem&gt;
  &lt;/Items&gt;
&lt;/HeaderGroup&gt;
...
</pre>        

        <cc1:EntityEdit ID="EntityEdit2" runat="server" Width="500px"/>
        
        <cc1:entityeditsavebutton id="btnAccept2" runat="server" width="64px"
            text="Save" EntityEditID="EntityEdit2" OnSuccess="alert('ok')" />
            
        <br />         
        <br />
        <br />     
        
        
            
        <span class="subtitle">Nested Controls</span>       
        <br />         
        <br />
        Another great value of Pampa.Net is the easy way to build nested controls. 
        A typical case of this need is when we have a list of states and a list of cities depending of the selected state.
        We can configure this dependence just setting the properties ParentId and ForeingProperty in the City item in the XML Configuration.
        <br />         
        <br />
        
<pre class="codeBlock">
<span class="keyword">public class</span> <span class="className">Address</span> : Pampa.CRUD.Core.<span class="className">IEntity</span>
{
    <span class="keyword">City</span> city;
    <span class="keyword">string</span> street;
    <span class="keyword">string</span> number;

    <span class="keyword">public</span> <span class="className">City</span> City
    {
        <span class="keyword">get</span> { <span class="keyword">return</span> city; }
        <span class="keyword">set</span> { city = value; }
    }

    <span class="keyword">public string</span> Street
    {
        <span class="keyword">get</span> { <span class="keyword">return</span> street; }
        <span class="keyword">set</span> { street = value; }
    }

    <span class="keyword">public string</span> Number
    {
        <span class="keyword">get</span> { <span class="keyword">return</span> number; }
        <span class="keyword">set</span> { number = value; }
    }

    ...
}
</pre>            

<pre class="codeBlock">
...
&lt;HeaderGroup Id="Address" Title="Address" Columns="1"&gt;
    &lt;Items&gt;
      &lt;EntityComboItem Id="City.State" Label="State" LabelWidth="100" ValueWidth="200" EntityName="Demo.Model.State, Demo.Model"&gt;
        &lt;Validations&gt;
          &lt;RequiredValidation ErrorMessage="State is required."/&gt;
        &lt;/Validations&gt;
      &lt;/EntityComboItem&gt;
      &lt;EntitySelectorItem Id="City" Label="City" LabelWidth="100" ValueWidth="200" EntityName="Demo.Model.City, Demo.Model" ParentId="City.State" ForeingProperty="State.ID"&gt;
        &lt;Validations&gt;
          &lt;RequiredValidation ErrorMessage="City is required."/&gt;
        &lt;/Validations&gt;
      &lt;/EntitySelectorItem&gt;
      &lt;TextItem Id="Street" Label="Street" LabelWidth="100" ValueWidth="200" MaxLength="20" TextMode="MultiLine" ValueHeight="50"&gt;
        &lt;Validations&gt;
          &lt;RequiredValidation ErrorMessage="Street is required."/&gt;
        &lt;/Validations&gt;
      &lt;/TextItem&gt;
      &lt;TextItem Id="Number" Label="Number" LabelWidth="100" ValueWidth="200" MaxLength="20"&gt;
        &lt;Validations&gt;
          &lt;RangeValidation DataType="Integer" ErrorMessage="Incorrect Number."/&gt;
        &lt;/Validations&gt;
      &lt;/TextItem&gt;
    &lt;/Items&gt;
&lt;/HeaderGroup&gt;
...
</pre>

To have this working class State should implement:
<pre>
<span class="keyword">public static</span> <span class="className">State</span>[] FindAll(<span class="keyword">string</span> orderBy)
</pre>
which should return all States and class City should implement:
<pre>
<span class="keyword">public static</span> <span class="className">City</span>[] FindAllByProperty(<span class="keyword">string</span> propertyName, <span class="keyword">object</span> propertyValue, <span class="keyword">string</span> orderBy)
</pre>
which should return all Cities where property of name equal to propertyName has the value propertyValue.<br/>
Implement this methods using Castle.ActiveRecord is trivial. 
You can see the full code of State and City classes in the Demo source code.
<br/>
<br/>

        <cc1:EntityEdit ID="EntityEdit3" runat="server" Width="500px"/>
        <br/>
        <br/>

        
        <span class="subtitle">Repetitive Groups</span>       
        <br />         
        <br />
        Repetitive Groups (or Details Group) allow to edit repetitive data related with our entity.
        For example, suppose we want to add a list of phones to our class Person.
        Then we will be able to edit this list of phones configuring a DetailsGroup in the Xml Configuration.
        <br />

<pre class="codeBlock">
<span class="keyword">public class</span> <span class="className">Person</span> : Pampa.CRUD.Core.<span class="className">IEntity</span>
{
    ...
    <span class="keyword">private</span> <span class="className">IList&lt;Phone&gt;</span> phones;

    <span class="keyword">public</span> Person()
    {
        phones = <span class="keyword">new</span> <span class="className">List&lt;Phone&gt;</span>();
    }

    ... 
    
    <span class="keyword">public</span> <span class="className">IList&lt;Phone&gt;</span> Phones
    {
        <span class="keyword">get</span> { return phones; }
        <span class="keyword">set</span> { phones = value; }
    }

    ...
}
</pre>  

<pre class="codeBlock">
...
&lt;DetailsGroup Id="Phones" Title="Person Phones" TypeName="Demo.Model.Phone, Demo.Model"&gt;
  &lt;Items&gt;
    &lt;StaticComboItem Id="Type" Label="Type" ValueWidth="200"&gt;
      &lt;ComboItems&gt;
        &lt;Item Text="Home" Value="H"/&gt;
        &lt;Item Text="Work" Value="W"/&gt;
      &lt;/ComboItems&gt;
    &lt;/StaticComboItem&gt;
    &lt;TextItem Id="Number" Label="Number" ValueWidth="200" MaxLength="20"&gt;
    &lt;/TextItem&gt;
  &lt;/Items&gt;
&lt;/DetailsGroup&gt;
...
</pre>
        
        <cc1:EntityEdit ID="EntityEdit4" runat="server" Width="500px" />

    </div>
    </form>
</body>
</html>
